home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * *
- * WinLIB PRO Revision II: Custom text editor *
- * *
- * Copyright (c) 1994, Bitgate Software *
- * *
- ********************************************************************/
-
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #include "winlib.h" /* WinLIB header file */
- #include "nkcc.h" /* Normalized Keycodes header file */
-
- #ifdef __TURBOC__
- #pragma warn -pia
- #endif
-
- #ifndef __FORMKEYBOARD__
- #define __FORMKEYBOARD__
- #endif
-
- /*
- * Turn the editing cursor off
- */
- GLOBAL void edit_off(WINDOW *win)
- {
- objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END);
- }
-
-
- /*
- * Turn on the editing cursor
- */
- GLOBAL void edit_on(WINDOW *win)
- {
- objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT);
- }
-
-
- /*
- * Reposition the cursor to an index
- * (It took a bit of thinking it out, but it worked in the end!)
- *
- * where = offset into string to put cursor on
- */
- GLOBAL void edit_pos(WINDOW *win, int where)
- {
- register char c, *t = win->tree[win->edobject].ob_spec.tedinfo->te_ptext;
-
- if (where!=win->edpos) {
- t += where;
-
- edit_off(win);
- c = *t;
- *t = 0;
- edit_on(win);
- *t = c;
- }
- }
-
- /*
- * Function to reposition cursor inside an object
- *
- * This code segment by Jan Starzynski
- * Modifications by Ken Hollis
- *
- * obj = Address of the root object (dialog box)
- * No = editable object which was clicked on
- * mx = X coordinate of mouse at time of click (from event info)
- *
- * Returns
- */
- GLOBAL int find_position(OBJECT *obj, int No, int mx)
- {
- int te_x= 0; /* Absolute coordinate of text */
- int P_text = 0; /* Position in text */
- int P_mask = 0; /* Position in mask */
- int size; /* Text font size */
- int i, Child; /* Children and the parent pointer */
-
- size = (obj[No].ob_spec.tedinfo->te_font == 3) ? 8 : 6;
- te_x = (obj[No].ob_spec.tedinfo->te_just)
- ? obj[No].ob_width - (obj[No].ob_spec.tedinfo->te_tmplen - 1) * size : 0;
- if(obj[No].ob_spec.tedinfo->te_just == 2)
- te_x /= 2;
- te_x += obj[No].ob_x + size / 2;
- Child = No;
- for (i = No - 1; 0 <= i; i--)
- if ((obj[i].ob_head <= Child) && (Child <= obj[i].ob_tail)) {
- Child = i;
- te_x += obj[i].ob_x;
- }
-
- while ((te_x < mx) && (P_mask < obj[No].ob_spec.tedinfo->te_tmplen - 1)) {
- if (obj[No].ob_spec.tedinfo->te_ptmplt[P_mask++] == '_')
- P_text++;
- te_x += size;
- }
- return P_text;
- }
-
-
- /*
- * Check to see if an object is hidden
- *
- * tree = Address of dialog box to check
- * obj = Object to check
- * flag = Flag to truly check for the object (usually TRUE)
- *
- * Returns: TRUE = it is hidden
- * FALSE = it is not
- */
- LOCAL int IsHidden(OBJECT *tree, int obj, int flag)
- {
- int index = obj, next;
-
- if (!(tree[obj].ob_flags & HIDETREE))
- if (flag == TRUE || !(tree[obj].ob_state & DISABLED)) {
- while ((next = tree[index].ob_next) != -1) {
- if ((tree[index].ob_flags & HIDETREE))
- return TRUE;
- index = next;
- }
- return FALSE;
- }
-
- return TRUE;
- }
-
-
- /*
- * Check for a specified flag against an object
- *
- * tree = Address of the dialog box
- * obj = Object to check
- * flag = Boolean value to truly check or not (usually TRUE)
- * mask = Mask to check for; make sure it's an integer value!
- *
- * Returns: TRUE = object is flag
- * FALSE = it is not
- */
- LOCAL int IsFlag(OBJECT *tree, int obj, int flag, int mask)
- {
- if ((flag & mask) && (!IsHidden(tree, obj, FALSE)))
- return TRUE;
-
- return FALSE;
- }
-
-
- /*
- * Jump to the first editable object
- *
- * tree = Address of the dialog box to go to the first object in
- *
- * Returns: index of the first object
- * 0 on failure
- */
- LOCAL int FirstEdit(OBJECT *tree)
- {
- int index = 0;
-
- do {
- index++;
- if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
- return index;
- }
- while (!(tree[index].ob_flags & LASTOB));
-
- return 0;
- }
-
-
- /*
- * Jump to the last editable object
- *
- * tree = Address of the dialog box to jump to the last object in
- *
- * Returns: index of the last object
- * 0 on failure
- */
- LOCAL int LastEdit(OBJECT *tree)
- {
- int index = 0, last = 0;
-
- do {
- index++;
- if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
- last = index;
- }
- while (!(tree[index].ob_flags & LASTOB));
-
- if (last)
- return last;
-
- return 0;
- }
-
-
- /*
- * Find next editable object
- *
- * tree = Address of the dialog box to search
- * cobj = Current object the cursor is at
- *
- * Returns: index of the next object
- * 0 on failure
- */
- LOCAL int NextEdit(OBJECT *tree, int cobj)
- {
- int index = cobj;
- int flag = FALSE;
-
- if (index) {
- while (!(tree[index].ob_flags & LASTOB)) {
- index++;
- if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
- return index;
- }
-
- if (!flag)
- return FirstEdit(tree);
- }
-
- return 0;
- }
-
-
- /*
- * Clear all editable fields
- *
- * tree = Object tree to clear out editable fields
- */
- LOCAL int ClearAllEdit(OBJECT *tree)
- {
- int index = 0;
-
- do {
- if (tree[++index].ob_flags & EDITABLE)
- tree[index].ob_spec.tedinfo->te_ptext = "\0";
- } while (!(tree[index].ob_flags & LASTOB));
-
- return FirstEdit(tree);
- }
-
-
- /*
- * Find the object before the current one
- *
- * tree = Address of the dialog box to search
- * cobj = Current object that the cursor is at
- *
- * Returns: the index of the previous editable object
- * 0 on failure
- */
- LOCAL int PrevEdit(OBJECT *tree, int cobj)
- {
- int index = cobj;
- int flag = FALSE;
-
- if (index) {
- do {
- index--;
- if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
- return index;
- }
- while (index);
-
- if (!flag)
- return LastEdit(tree);
- }
-
- return 0;
- }
-
-
- /*
- * Customized form_keybd call
- *
- * win = Window structure
- * key = Keyboard keycode from EvntMulti
- * kstate = Keyboard status
- * nchr = Processed keycode (0 if handled, otherwise, it
- * returns the keycode that was typed.)
- *
- * Returns: 0 if an exitobject was selected
- */
- GLOBAL int WForm_keybd(WINDOW *win, int key, int kstate, int *nobj, int *nchr)
- {
- int n_key;
-
- n_key = nkc_tconv((key & 0xff) | (((long) key & 0xff00) << 8) | ((long) kstate << 24)) & ~(NKF_FUNC | NKF_RESVD | NKF_NUM);
- *nchr = 0;
-
- if ((!win->edobject && n_key == NK_RET) || (n_key == (NK_RET | NKF_CTRL))) {
- int i = 0;
- OBJECT *obj = win->tree;
-
- do {
- if (obj->ob_flags & DEFAULT) {
- *nobj = i;
- return FALSE;
- }
- i++;
- } while (!((obj++)->ob_flags & LASTOB));
-
- *nobj = 0;
- return TRUE;
- }
-
- if (!win->edobject || n_key & NKF_ALT) {
- int i = 0, mask = (toupper(n_key & 0xff) & 0x7f) << 8;
- OBJECT *obj = win->tree;
-
- do {
- if (((obj->ob_type & 0x7f00) == mask) && !(obj->ob_state & DISABLED) && ((obj->ob_flags & SELECTABLE) || (obj->ob_flags & EXIT))) {
- *nobj = i;
- return FALSE;
- }
- i++;
- }
- while (!((obj++)->ob_flags & LASTOB));
- }
-
- if (win->edobject) {
- register char *text = win->tree[win->edobject].ob_spec.tedinfo->te_ptext;
-
- switch (n_key) {
- case NK_ENTER:
- case NK_DOWN:
- case NK_TAB:
- case NK_RET:
- edit_off(win);
- win->edobject = NextEdit(win->tree, win->edobject);
- win->edpos = (int) strlen(text);
- edit_on(win);
- break;
-
- case NK_UP:
- case NK_TAB | NKF_LSH:
- case NK_TAB | NKF_RSH:
- edit_off(win);
- win->edobject = PrevEdit(win->tree, win->edobject);
- win->edpos = (int) strlen(text);
- edit_on(win);
- break;
-
- case NK_UNDO:
- WCallUndoDispatcher(win);
- break;
-
- case NK_HELP:
- WCallHelpDispatcher(win);
- break;
-
- case NK_F1:
- WCallFKeyDispatcher(win, 1);
- break;
-
- case NK_F2:
- WCallFKeyDispatcher(win, 2);
- break;
-
- case NK_F3:
- WCallFKeyDispatcher(win, 3);
- break;
-
- case NK_F4:
- WCallFKeyDispatcher(win, 4);
- break;
-
- case NK_F5:
- WCallFKeyDispatcher(win, 5);
- break;
-
- case NK_F6:
- WCallFKeyDispatcher(win, 6);
- break;
-
- case NK_F7:
- WCallFKeyDispatcher(win, 7);
- break;
-
- case NK_F8:
- WCallFKeyDispatcher(win, 8);
- break;
-
- case NK_F9:
- WCallFKeyDispatcher(win, 9);
- break;
-
- case NK_F10:
- WCallFKeyDispatcher(win, 10);
- break;
-
- case NK_CLRHOME | NKF_CTRL:
- {
- int x, y, w, h;
-
- win->edobject = ClearAllEdit(win->tree);
- WWindGet(win, WF_WORKXYWH, &x, &y, &w, &h);
- WRedrawWindow(win, x, y, w, h);
- }
- break;
-
- case NK_LEFT | NKF_LSH:
- case NK_LEFT | NKF_RSH:
- edit_pos(win, 0);
- break;
-
- case NK_RIGHT | NKF_LSH:
- case NK_RIGHT | NKF_RSH:
- edit_pos(win, (int) strlen(text));
- break;
-
- case NK_RIGHT | NKF_CTRL:
- {
- char *ptr = text + win->edpos;
-
- if (*ptr) {
- while (*(++ptr))
- if (isalnum(*ptr) && !isalnum(*(ptr - 1)))
- break;
-
- edit_pos(win, (int) (ptr - text));
- }
- }
- break;
-
- case NK_LEFT | NKF_CTRL:
- if (win->edpos) {
- char *ptr = text + win->edpos;
-
- while (text != --ptr)
- if (!isalnum(*ptr) && text != ptr - 1)
- if (isalnum(*(ptr - 1)))
- break;
-
- edit_pos(win, (int) (ptr - text));
- }
- break;
-
- case NK_LEFT:
- {
- int pos = win->edpos;
-
- pos--;
- if (pos<0) pos = 0;
- edit_pos(win, pos);
- }
- break;
-
- case NK_RIGHT:
- {
- int pos = win->edpos;
-
- pos++;
- if (pos>(int) strlen(text)) pos = (int) strlen(text);
- edit_pos(win, pos);
- }
- break;
-
- case NK_UP | NKF_LSH:
- case NK_UP | NKF_RSH:
- case NK_CLRHOME:
- {
- int prev = win->edobject;
- int storage;
-
- storage = FirstEdit(win->tree);
- if (storage == prev) {
- win->edobject = prev;
- edit_pos(win, 0);
- } else {
- edit_off(win);
- win->edobject = storage;
- edit_on(win);
- }
- }
- break;
-
- case NK_CLRHOME | NKF_LSH:
- case NK_CLRHOME | NKF_RSH:
- case NK_DOWN | NKF_LSH:
- case NK_DOWN | NKF_RSH:
- {
- int prev = win->edobject;
- int storage;
-
- storage = LastEdit(win->tree);
- if (storage == prev) {
- win->edobject = prev;
- edit_pos(win, 0);
- } else {
- edit_off(win);
- win->edobject = storage;
- edit_on(win);
- }
- }
- break;
-
- case NK_INS:
- WGrafMouse(ARROW);
- {
- int edittype = WFind_EditType(win);
- *nchr = (char) WAscii_Table(edittype);
- }
- break;
-
- default:
- *nchr = key;
- break;
- }
- }
-
- *nobj = win->edobject;
-
- return TRUE;
- }
-
- GLOBAL int WFind_EditType(WINDOW *win)
- {
- int type, pos = 0, len = strlen(win->tree[win->edobject].ob_spec.tedinfo->te_pvalid);
-
- do {
- pos++;
-
- switch(win->tree[win->edobject].ob_spec.tedinfo->te_pvalid[pos]) {
- case '9': return E_NUMERIC;
- case 'a': return E_LOW_ASCII;
- case 'n': return E_LOW_NUMERIC;
- case 'p': return E_LOW_PATH;
- case 'A': return E_UP_ASCII;
- case 'N': return E_UP_NUMERIC;
- case 'P': return E_UP_PATH;
- case 'X': return E_ANY;
- case 'S': return E_SPECIAL;
- }
- } while (pos < len);
-
- return 0;
- }
-